package com.r2coding.domain.strategy.service.raffle;

import com.r2coding.domain.strategy.model.entity.RaffleAwardEntity;
import com.r2coding.domain.strategy.model.entity.RaffleFactorEntity;
import com.r2coding.domain.strategy.model.entity.RuleActionEntity;
import com.r2coding.domain.strategy.model.entity.StrategyEntity;
import com.r2coding.domain.strategy.model.valobj.RuleLogicCheckTypeVO;
import com.r2coding.domain.strategy.model.valobj.StrategyAwardRuleModelVO;
import com.r2coding.domain.strategy.repository.IStrategyRepository;
import com.r2coding.domain.strategy.service.armory.IStrategyDispatch;
import com.r2coding.domain.strategy.service.rule.factory.DefaultLogicFactory;
import com.r2coding.types.enums.ResponseCode;
import com.r2coding.types.exception.AppException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import javax.annotation.Resource;

/**
 * @author caolx
 * @description 抽奖抽象类 定义抽奖流程模板
 * @date 2025/8/2 11:28
 */
@Slf4j
public abstract class AbstractRaffleStrategy implements IRaffleStrategy {

    @Resource
    private IStrategyRepository strategyRepository;
    @Resource
    private IStrategyDispatch strategyDispatch;

    @Override
    public RaffleAwardEntity performRaffle(RaffleFactorEntity raffleFactorEntity) {
        // 1、校验请求参数合法性
        String userId = raffleFactorEntity.getUserId();
        Long strategyId = raffleFactorEntity.getStrategyId();
        if (null == strategyId || StringUtils.isBlank(userId)) {
            throw new AppException(ResponseCode.ILLEGAL_PARAMETER.getCode(), ResponseCode.ILLEGAL_PARAMETER.getInfo());
        }

        // 2、策略查询
        StrategyEntity strategyEntity = strategyRepository.queryStrategyEntity(strategyId);

        // 3、【抽奖前】规则过滤
        RuleActionEntity<RuleActionEntity.RaffleBeforeEntity> ruleActionEntity = this.doCheckRaffleBeforeLogic(raffleFactorEntity, strategyEntity.ruleModels());
        if (RuleLogicCheckTypeVO.TAKE_OVER.getCode().equals(ruleActionEntity.getCode())) {
            // 如果是白、黑名单用户， 则直接返回固定的奖品ID
            if (DefaultLogicFactory.LogicModel.RULE_WHITELIST.getCode().equals(ruleActionEntity.getRuleModel()) ||
                    DefaultLogicFactory.LogicModel.RULE_BLACKLIST.getCode().equals(ruleActionEntity.getRuleModel())) {
                return RaffleAwardEntity.builder()
                        .userId(userId)
                        .strategyId(strategyId)
                        .awardId(ruleActionEntity.getData().getAwardId())
                        .build();
            } else if (DefaultLogicFactory.LogicModel.RULE_WEIGHT.getCode().equals(ruleActionEntity.getRuleModel())) {
                // 根据权重返回的信息进行抽奖
                Integer ruleWeightValue = ruleActionEntity.getData().getRuleWeightValue();
                Integer awardId = strategyDispatch.getRuleWeightRandomAwardId(strategyId, ruleWeightValue);
                return RaffleAwardEntity.builder()
                        .userId(userId)
                        .strategyId(strategyId)
                        .awardId(awardId)
                        .build();
            }
        }
        // 4、默认抽奖流程
        Integer randomAwardId = strategyDispatch.getRandomAwardId(strategyId);

        // 5. 查询奖品规则「抽奖中（拿到奖品ID时，过滤规则）、抽奖后（扣减完奖品库存后过滤，抽奖中拦截和无库存则走兜底）」
        StrategyAwardRuleModelVO strategyAwardRuleModelVO = strategyRepository.queryStrategyAwardRuleModelVO(strategyId, randomAwardId);
        RaffleFactorEntity raffleCenterFactorEntity = RaffleFactorEntity.builder()
                .userId(userId)
                .strategyId(strategyId)
                .awardId(randomAwardId)
                .build();

        // 6、【抽奖中】规则过滤
        RuleActionEntity<RuleActionEntity.RaffleCenterEntity> ruleActionCenterEntity = this.doCheckRaffleCenterLogic(raffleCenterFactorEntity, strategyAwardRuleModelVO.raffleCenterRuleModels());
        if (RuleLogicCheckTypeVO.TAKE_OVER.getCode().equals(ruleActionCenterEntity.getCode())) {
            log.info("【临时日志】- 【抽奖中】规则拦截，通过抽奖后规则 rule_luck_award 走兜底奖励");
            return RaffleAwardEntity.builder()
                    .awardDesc("【抽奖中】规则拦截，通过抽奖后规则 rule_luck_award 走兜底奖励")
                    .build();
        }

        return RaffleAwardEntity.builder()
                .userId(userId)
                .strategyId(strategyId)
                .awardId(randomAwardId)
                .build();
    }

    /**
     * 执行【抽奖前】规则过滤
     *
     * @param raffleFactorEntity 抽奖因子
     * @param logics             需要过滤的模型
     * @return 规则过滤结果
     */
    protected abstract RuleActionEntity<RuleActionEntity.RaffleBeforeEntity> doCheckRaffleBeforeLogic(RaffleFactorEntity raffleFactorEntity, String... logics);

    /**
     * 执行【抽奖中】规则过滤
     *
     * @param raffleFactorEntity 抽奖因子
     * @param logics             抽奖中规则模型
     * @return 【抽奖中】规则校验结果
     */
    protected abstract RuleActionEntity<RuleActionEntity.RaffleCenterEntity> doCheckRaffleCenterLogic(RaffleFactorEntity raffleFactorEntity, String... logics);
}
